﻿#include "main.h"
#include "key.h"

#define SW_PORT_SOURCE GPIO_PORT_SOURCE_GPIOB /*!< the port exti source of key */
/* the pin exti source of key */
#define SW4_PIN_SOURCE GPIO_PIN_SOURCE_15
#define SW5_PIN_SOURCE GPIO_PIN_SOURCE_14
#define SW6_PIN_SOURCE GPIO_PIN_SOURCE_13
#define SW7_PIN_SOURCE GPIO_PIN_SOURCE_12
/* the exti line of key */
#define SW_EXTI_LINE (exti_line_enum)(EXTI_12 | EXTI_13 | EXTI_14 | EXTI_15)


/**
 * @brief key initializtion
 * @details sw4 to PB15
 *          sw5 to PB14
 *          sw6 to PB13
 *          sw7 to PB12
 * @param  None
 */
void key_init(void)
{
    /* setup GPIOB and AFIO clock */
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_AF);

    /* configure the GPIO pin as input floating */
    gpio_init(SW_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, SW4 | SW5 | SW6 | SW7);

    /* initializtion exti line 12~15 */
    exti_init(SW_EXTI_LINE, EXTI_INTERRUPT, EXTI_TRIG_BOTH);

    /* exti port source select */
    gpio_exti_source_select(SW_PORT_SOURCE, SW4_PIN_SOURCE);
    gpio_exti_source_select(SW_PORT_SOURCE, SW5_PIN_SOURCE);
    gpio_exti_source_select(SW_PORT_SOURCE, SW6_PIN_SOURCE);
    gpio_exti_source_select(SW_PORT_SOURCE, SW7_PIN_SOURCE);

    /* enable exti interrupt */
    exti_interrupt_enable(SW_EXTI_LINE);
    exti_interrupt_flag_clear(SW_EXTI_LINE);

    /* coinfigure interrupt request passage */
    nvic_irq_enable(EXTI10_15_IRQn, 6, 0);
}
INIT_BSP_EXPORT(key_init);

/**
 * @brief rewrite the callback function of exti10-15
 * @param exti_inter
 */
void exti_10_15_callbake_it(uint32_t exti_inter)
{
    extern TaskHandle_t keyTaskHandle;
    configASSERT(NULL != keyTaskHandle);

    if(EXTI_INTEN_INTEN12 == exti_inter) // sw7
    {
        BaseType_t pxHigherPriorityTaskWoken = pdFALSE;

        // log("SW7\r\n");

        /* woken task by send notify */
        xTaskNotifyFromISR(keyTaskHandle, KEY_EVENT_7, eSetBits, &pxHigherPriorityTaskWoken);
        portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
    }
    else if(EXTI_INTEN_INTEN13 == exti_inter) // sw6
    {
        BaseType_t pxHigherPriorityTaskWoken = pdFALSE;

        // log("SW6\r\n");

        /* woken task by send notify */
        xTaskNotifyFromISR(keyTaskHandle, KEY_EVENT_6, eSetBits, &pxHigherPriorityTaskWoken);
        portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
    }
    else if(EXTI_INTEN_INTEN14 == exti_inter) // sw5
    {
        BaseType_t pxHigherPriorityTaskWoken = pdFALSE;

        // log("SW5\r\n");

        /* woken task by send notify */
        xTaskNotifyFromISR(keyTaskHandle, KEY_EVENT_5, eSetBits, &pxHigherPriorityTaskWoken);
        portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
    }
    else if(EXTI_INTEN_INTEN15 == exti_inter) // sw4
    {
        BaseType_t pxHigherPriorityTaskWoken = pdFALSE;

        // log("SW4\r\n");

        /* woken task by send notify */
        xTaskNotifyFromISR(keyTaskHandle, KEY_EVENT_4, eSetBits, &pxHigherPriorityTaskWoken);
        portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);

    }
}
